<!DOCTYPE html>

<!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
<!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
<!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
<!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
    <head>
        <meta charset="utf-8">
        <title>Autocommand Groups / Learn Vimscript the Hard Way</title>
        <meta name="description" content="">
        <meta name="author" content="Steve Losh">
        <!--[if lt IE 9]>
            <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
        <![endif]-->

        <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

        <link href="/static/styles/skeleton/base.css" rel="stylesheet" type="text/css" />
        <link href="/static/styles/skeleton/skeleton.css" rel="stylesheet" type="text/css" />
        <link href="/static/styles/skeleton/layout.css" rel="stylesheet" type="text/css" />

        <link href="/static/styles/tango.css" rel="stylesheet" type="text/css" />
        <link href="/static/styles/style.less" rel="stylesheet/less" type="text/css" />

        <script type="text/javascript" src="/static/scripts/less.js"></script>
    </head>

    <body class="">
        <div class="container">
            <header class="sixteen columns">
                <h1><a href="/">Learn Vimscript the Hard Way</a></h1>
            </header>

            
    <section class="nav three columns">
        
<ul>
<li><a href="#autocommand-groups">Autocommand Groups</a><ul>
<li><a href="#the-problem">The Problem</a></li>
<li><a href="#grouping-autocommands">Grouping Autocommands</a></li>
<li><a href="#clearing-groups">Clearing Groups</a></li>
<li><a href="#using-autocommands-in-your-vimrc">Using Autocommands in Your Vimrc</a></li>
<li><a href="#exercises">Exercises</a></li>
</ul>
</li>
</ul>


        <div class="prevnext">
            
                <a class="prev" href="13.html">&laquo; Prev</a>
            
            
                <a class="next" href="15.html">Next &raquo;</a>
            
        </div>
    </section>

    <section class="content twelve columns offset-by-one">
        <div> 
<h1 id="autocommand-groups">Autocommand Groups</h1>
<p>A few chapters ago we learned about autocommands.  Run the following command:</p>
<pre class="codehilite"><code class="language-vim">:autocmd BufWrite * :echom "Writing buffer!"</code></pre>


<p>Now write the current buffer with <code>:write</code> and run <code>:messages</code> to view the
message log.  You should see the <code>Writing buffer!</code> message in the list.</p>
<p>Now write the current buffer again and run <code>:messages</code> to view the message log.
You should see the <code>Writing buffer!</code> message in the list twice.</p>
<p>Now run the exact same autocommand again:</p>
<pre class="codehilite"><code class="language-vim">:autocmd BufWrite * :echom "Writing buffer!"</code></pre>


<p>Write the current buffer one more time and run <code>:messages</code>.  You will see the
<code>Writing buffer!</code> message in the list <em>four</em> times.  What happened?</p>
<p>When you create an autocommand like this Vim has no way of knowing if you want
it to replace an existing one.  In our case, Vim created two <em>separate</em>
autocommands that each happen to do the same thing.</p>
<h2 id="the-problem">The Problem</h2>
<p>Now that you know it's possible to create duplicate autocommands, you may be
thinking: "So what?  Just don't do that!"</p>
<p>The problem is that sourcing your <code>~/.vimrc</code> file rereads the entire file,
including any autocommands you've defined!  This means that every time you
source your <code>~/.vimrc</code> you'll be duplicating autocommands, which will make Vim
run slower because it executes the same commands over and over.</p>
<p>To simulate this, try running the following command:</p>
<pre class="codehilite"><code class="language-vim">:autocmd BufWrite * :sleep 200m</code></pre>


<p>Now write the current buffer.  You may or may not notice a slight sluggishness
in Vim's writing time.  Now run the command three more times:</p>
<pre class="codehilite"><code class="language-vim">:autocmd BufWrite * :sleep 200m
:autocmd BufWrite * :sleep 200m
:autocmd BufWrite * :sleep 200m</code></pre>


<p>Write the file again.  This time the slowness will be more apparent.</p>
<p>Obviously you won't have any autocommands that do nothing but sleep, but the
<code>~/.vimrc</code> of a seasoned Vim user can easily reach 1,000 lines, many of which will
be autocommands.  Combine that with autocommands defined in any installed
plugins and it can definitely affect performance.</p>
<h2 id="grouping-autocommands">Grouping Autocommands</h2>
<p>Vim has a solution to the problem.  The first step is to group related
autocommands into named groups. </p>
<p>Open a fresh instance of Vim to clear out the autocommands from before, then run
the following commands:</p>
<pre class="codehilite"><code class="language-vim">:augroup testgroup
:    autocmd BufWrite * :echom "Foo"
:    autocmd BufWrite * :echom "Bar"
:augroup END</code></pre>


<p>The indentation in the middle two lines is insignificant.  You don't have to
type it if you don't want to.</p>
<p>Write a buffer and check <code>:messages</code>.  You should see both <code>Foo</code> and <code>Bar</code>.  Now
run the following commands:</p>
<pre class="codehilite"><code class="language-vim">:augroup testgroup
:    autocmd BufWrite * :echom "Baz"
:augroup END</code></pre>


<p>Try to guess what will happen when you write the buffer again.  Once you have
a guess in mind, write the buffer and check <code>:messages</code> to see if you were
correct.</p>
<h2 id="clearing-groups">Clearing Groups</h2>
<p>What happened when you wrote the file?  Was it what you expected?</p>
<p>If you thought Vim would replace the group, you can see that you guessed
wrong.  Don't worry, most people think the same thing at first (I know I did).</p>
<p>When you use <code>augroup</code> multiple times Vim will <em>combine</em> the groups each time.</p>
<p>If you want to <em>clear</em> a group you can use <code>autocmd!</code> inside the group.  Run the
following commands:</p>
<pre class="codehilite"><code class="language-vim">:augroup testgroup
:    autocmd!
:    autocmd BufWrite * :echom "Cats"
:augroup END</code></pre>


<p>Now try writing your file and checking <code>:messages</code>.  This time Vim only echoed
<code>Cats</code> when you wrote the file.</p>
<h2 id="using-autocommands-in-your-vimrc">Using Autocommands in Your Vimrc</h2>
<p>Now that we know how to group autocommands and clear those groups, we can use
this to add autocommands to <code>~/.vimrc</code> that don't add a duplicate every time we
source it.</p>
<p>Add the following to your <code>~/.vimrc</code> file:</p>
<pre class="codehilite"><code class="language-vim">augroup filetype_html
    autocmd!
    autocmd FileType html nnoremap &lt;buffer&gt; &lt;localleader&gt;f Vatzf
augroup END</code></pre>


<p>We enter the <code>filetype_html</code> group, immediately clear it, define an autocommand,
and leave the group.  If we source <code>~/.vimrc</code> again the clearing will prevent
Vim from adding duplicate autocommands.</p>
<h2 id="exercises">Exercises</h2>
<p>Go through your <code>~/.vimrc</code> file and wrap <em>every</em> autocommand you have in groups
like this.  You can put multiple autocommands in the same group if it makes
sense to you.</p>
<p>Try to figure out what the mapping in the last example does.</p>
<p>Read <code>:help autocmd-groups</code>.</p></div>

        <div class="prevnext">
            
                <a class="prev" href="13.html">&laquo; Previous</a>
            
            
                <a class="next" href="15.html">Next &raquo;</a>
            
        </div>
    </section>


            <footer class="sixteen columns">
                Made by <a href="http://stevelosh.com">Steve Losh</a>.

                <a href="/license.html">License</a>.

                Built with
                <a href="http://bitbucket.org/sjl/bookmarkdown/">Bookmarkdown</a>.
            </footer>
        </div>

        
            <script type="text/javascript">
                var _gaq = _gaq || [];
                _gaq.push(['_setAccount', 'UA-15328874-8']);
                _gaq.push(['_trackPageview']);

                (function() {
                 var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
                 ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
                 var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
                 })();
            </script>
        

        
            <script type="text/javascript">
                var _gauges = _gauges || [];
                (function() {
                 var t   = document.createElement('script');
                 t.type  = 'text/javascript';
                 t.async = true;
                 t.id    = 'gauges-tracker';
                 t.setAttribute('data-site-id', '4e8f83b7f5a1f546e200000d');
                 t.src = '//secure.gaug.es/track.js';
                 var s = document.getElementsByTagName('script')[0];
                 s.parentNode.insertBefore(t, s);
                 })();
             </script>
        
    </body>
</html>
